﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Dsl.Ped.Common.Commands;
using GalaSoft.MvvmLight.Command;

namespace Dsl.Ped.Controls.ButtonActionSelector
{
    /// <summary>
    /// This is the <see cref="Control"/> that displays a list of actions to be executed
    /// after the user clicks the <see cref="Button"/>
    /// </summary>
    [TemplatePart(Name = "PART_MainButton", Type = typeof(Button))]
    [TemplatePart(Name = "PART_MainContextMenu", Type = typeof(ContextMenu))]
    public class ButtonActionSelectorControl : ContentControl
    {
        /// <summary>
        /// Property that refers to all available commands
        /// </summary>
        public static DependencyProperty CommandsProperty;

        /// <summary>
        /// Property that refers to parameters used for the execution of comands
        /// </summary>
        public static DependencyProperty CommandParameterProperty;

        /// <summary>
        /// <see cref="ContextMenu"/> displayed for the execution of actions
        /// </summary>
        private ContextMenu MainContextMenu;

        /// <summary>
        /// <see cref="Button"/> that displays the <see cref="MainContextMenu"/>
        /// </summary>
        private Button MainButton;

        /// <summary>
        /// Static constructor, register all <see cref="DependencyProperty"/> properties
        /// </summary>
        static ButtonActionSelectorControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonActionSelectorControl), new FrameworkPropertyMetadata(typeof(ButtonActionSelectorControl)));

            CommandsProperty = DependencyProperty.Register(
                "Commands",
                typeof(List<IMenuCommand>),
                typeof(ButtonActionSelectorControl),
                new FrameworkPropertyMetadata(null));

            CommandParameterProperty = DependencyProperty.Register(
                "CommandParameter",
                typeof(object),
                typeof(ButtonActionSelectorControl),
                new FrameworkPropertyMetadata(null));
        }

        /// <summary>
        /// Gets or sets all available <see cref="IMenuCommand"/> to be available 
        /// in the <see cref="MainContextMenu"/> for the execution
        /// </summary>
        public List<IMenuCommand> Commands
        {
            get
            {
                return (List<IMenuCommand>)GetValue(CommandsProperty);
            }
            set
            {
                SetValue(CommandsProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets a command parameter used for the execution of <see cref="IMenuCommand"/>
        /// available in <see cref="MainContextMenu"/>
        /// </summary>
        public object CommandParameter
        {
            get
            {
                return (object)this.GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        /// <summary>
        /// Execute this method when the default template is applied to the <see cref="ButtonActionSelectorControl"/>
        /// 
        /// Instantiates all the necessary variables like <see cref="MainButton"/>, <see cref="MainContextMenu"/>
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.MainButton = (Button)base.GetTemplateChild("PART_MainButton");
            this.MainContextMenu = (ContextMenu)base.GetTemplateChild("PART_MainContextMenu");

            if (MainButton == null) throw new Exception("PART_MainButton missing in the template");
            if (MainContextMenu == null) throw new Exception("PART_MainContextMenu missing in the template");

            if (this.MainContextMenu != null)
            {
                this.MainContextMenu.PlacementTarget = this.MainButton;
                this.MainContextMenu.Placement = PlacementMode.Relative;
                this.MainContextMenu.IsOpen = false;
            }

            if (this.MainButton != null)
            {
                this.MainButton.Command = new RelayCommand(this.ButtonClick);
            }
        }

        /// <summary>
        /// Method executed when the <see cref="MainButton"/> is clicked
        /// </summary>
        private void ButtonClick()
        {
            if (Commands == null || Commands.Count == 0) return;
            
            if (Commands.Count == 1)
            {
                ICommand command = (ICommand)Commands[0];
                if (command.CanExecute(CommandParameter))
                {
                    command.Execute(CommandParameter);
                }

                return;
            }
            this.MainContextMenu.IsOpen = true;
        }
    }
}
